package org.fjsei.yewu.controller;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.filter.SimplePropertyPreFilter;
import com.querydsl.core.types.Predicate;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import md.specialEqp.inspect.Isp;
import md.specialEqp.inspect.IspPi;
import md.specialEqp.inspect.IspRepository;
import md.specialEqp.inspect.QIsp;
import org.fjsei.yewu.aop.MetricsLogger;
import org.fjsei.yewu.dto.GlobalIdRequest;
import org.fjsei.yewu.dto.GlobalIdResponse;
import org.fjsei.yewu.job.controller.model.CreateJobDetailsRequestModel;
import org.fjsei.yewu.jpa.QBeanMy;
import org.fjsei.yewu.jyjc.DtHandleUtil;
import org.fjsei.yewu.jyjc.model.*;
import org.fjsei.yewu.repository.Teacher;
import org.fjsei.yewu.service.JpaService;
import org.fjsei.yewu.util.Tool;
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
import org.hibernate.internal.CoreMessageLogger;
import org.jboss.logging.Logger;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.repository.query.FluentQuery;
import org.springframework.http.HttpEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

//import static org.fjsei.yewu.job.QuartzOldConfig.createJobDetail;
import static org.springframework.transaction.annotation.Propagation.REQUIRES_NEW;


/**测试用的，正式生产环境不要用。
 * @program: 特种设备业务平台
 * @description:
 * @author: herzhang
 * @create: 2018-05-02 11:15
 */

@PreAuthorize("hasAnyRole('Master')")
@Slf4j
@Validated
@RestController
@RequestMapping("/teacher")
public class JpaTestController {
    private final org.slf4j.Logger logger = LoggerFactory.getLogger(JpaTestController.class);
    @Autowired   private IspRepository iSPRepository;
    @Value("${sei.Jcjk.password:}")
    private String jcpassword;
    @Value("${sei.Jcjk.username:}")
    private String jcusername;

    private static final CoreMessageLogger LOG = Logger.getMessageLogger(
            CoreMessageLogger.class,
            SqlExceptionHelper.class.getName()
    );

    @Resource
    private JpaService jpaService;
    //@Autowired  private JpaService jpaService;

/*  @GetMapping
    public List<Teacher> getAllTeacher() {
        return jpaService.getAllTeacher();
    }*/

    //批处理：测试数据。
    @GetMapping(value = "/{name}")
    public Teacher getTeacher(@PathVariable final String name) {
        jpaService.testIt();
        return jpaService.getTeacher(name);
    }

    //实际POST测试成功： URL=  http://27.151.117.65:8673/teacher/teacher
    //Content-Type application/json; charset=utf-8   /   Cache-Control no-cache
    //请求Body = {"id":null,"name":"意查询","age":"567","course":"b是没变n2"}   ；应答体={}
    ///@Transactional   @Transactional
/*    @RequestMapping(method = RequestMethod.POST, value = "/teacher")
    public void addTopic(@RequestBody Teacher topic) {
        jpaService.addTeacher(topic);
        //保存数据库成功
    }*/

    /*Rest复杂点的URI映射类,测试: 是可以自动把?parm=val&...的URL参数统统转成TaskQueryParam类的成员变量。URI文本串很长了,例子如下:
            GET http://localhost:8673/teacher/tasks?assignee=gt12w&processDefinitionKey=水电费f
            Accept: application/json
            http://192.168.171.3:8673/teacher/tasks?finished=true&pageNo=2347&startedAfter=2021-11-23%2011:22:55
    * */
//    @GetMapping("/tasks")
//    public RespResult<TaskVo<BizPaymentProcessInfo>> getTasks(TaskQueryParam taskQueryParam) {
//        log.info("get payment tasks, param: {}", taskQueryParam);
//        RespResult<TaskVo<BizPaymentProcessInfo>> taskVoRespResult = new RespResult<TaskVo<BizPaymentProcessInfo>>();
//        taskVoRespResult.setRespCode(3584);
//        log.info("get payment tasks, Result: {}", taskVoRespResult);
//        return taskVoRespResult;
//    }


    //POST http://192.168.3.151:8673/teacher/setage2?userId=1&age=的s&mny=1.4
    @PostMapping("setage2")
    @Transactional(propagation = REQUIRES_NEW)
    public HttpEntity<Integer> transfer(
            @RequestParam("userId") UUID userId,
            @RequestParam("age") String age,
            @RequestParam("mny") BigDecimal mny
    ) {
        jpaService.setTeacherAge(userId,age);
        return ResponseEntity.ok().build();
    }

//    @GetMapping(value = "/{id}/getid")
//    //@Transactional不用添加 没毛病
//    public RespResult<String> getTeacher(@PathVariable final Long id) {
//        RespResult<String> respResult=new RespResult<>();
//        Teacher teacher=jpaService.getTeacherById(id);
//        respResult.setData(teacher.getAge());
//        respResult.setRespCode(240);
//        return respResult;
//    }

    /*
     * http://localhost:8080/getCatByaddressIdAndByAge?id=16&age=17
     * @param id
     * @param age
     * @return
    @RequestMapping(value="/getCatByaddressIdAndByAge",produces={"application/json;charset=UTF-8"})
    public List<Cat> getCatByaddressIdAndByAge(Long id,int age){
        List<Cat> catByaddressIdAndByAge = catService.getCatByaddressIdAndByAge(id, age);
        return catByaddressIdAndByAge;
    }
    *
    @PutMapping
    public RestResult put(@RequestBody SysJobMain main) throws SchedulerException {
    @PostMapping("start/{ids}")
    public RestResult startJob(@PathVariable String[] ids) throws SchedulerException {
    //新增项目
    @PostMapping
    public RestResult post(@RequestBody SdProjMain main)
    //修改项目
    @PutMapping
    public RestResult put(@RequestBody SdProjMain main)
    //删除项目
    @DeleteMapping("{ids}")
    public RestResult delete(@PathVariable String[] ids)
     */

    /* @GetMapping("/tasks/history")

     public class BasePageParam {
        private Integer pageNo = 1;
        private Integer pageSize = 10;
        @Data
        public class TaskQueryParam extends BasePageParam {
             * 任务处理者
            private String assignee;

     * 查询用户待处理任务
     * @param taskQueryParam 任务查询参数
     * @return 响应结果  #奇怪% TaskQueryParam %
    @GetMapping("/tasks")
    public RespResult<TaskVo<BizPaymentProcessInfo>> getTasks(TaskQueryParam taskQueryParam) {
        log.info("get payment tasks, param: {}", taskQueryParam);
        RespResult<TaskVo<BizPaymentProcessInfo>> taskVoRespResult = this.paymentProcessInfoService.queryTasks(taskQueryParam);
        log.info("get payment tasks, param: {}", taskQueryParam);
        return taskVoRespResult;
    }
    com\baomidou\mybatis-plus-core\3.5.1\mybatis-plus-core + implementation 'org.mybatis:mybatis:'
     * 确认支付
     * @param paymentConfirmParam 确认参数
     * @return 响应结果
    @PutMapping("/confirm")
    public RespResult<Integer> confirmPayment(@Validated @RequestBody PaymentConfirmParam paymentConfirmParam) {
        log.info("confirm payment, param: {}", paymentConfirmParam);
        RespResult respResult = this.paymentProcessInfoService.confirmPayment(paymentConfirmParam);
        log.info("confirm payment, result: {}", respResult);
        return respResult;
    }
    */

    /* 基于HATEOAS模式:更啰嗦附加信息，<dependency> spring-boot-starter-hateoas </dependency>
    @EnableHypermediaSupport(type = EnableHypermediaSupport.HypermediaType.HAL) = xxxApp class{}
    @Entity  Model类
    public class SysUserInfo extends ResourceSupport implements Serializable{}
    接口调用，
    @GetMapping("/findBySysUserId/{userId}")
     public SysUserInfo findBySysUserId(@PathVariable("userId") long userId) {
      if (LOG.isInfoEnabled()) {
       LOG.info("请求参数userId : {}" , userId);
      }
      Optional<SysUserInfo> sysUserInfo = Optional.ofNullable(sysUserRepository.findByUserId(userId));
      if (!sysUserInfo.isPresent()) {
       throw new NotFoundException("查询不到用户信息! userId:"+userId);
      }
      //Resource<SysUserInfo> resource = new Resource<SysUserInfo>(sysUserInfo.get());
      ControllerLinkBuilder linkBuilder = linkTo(methodOn(this.getClass()).findBySysUserId(userId));  /WebMvcLinkBuilder.methodOn;
      sysUserInfo.get().add(linkBuilder.withRel("findBySysUserId"));
      return sysUserInfo.get();
     }
    public HttpEntity<BigDecimal> transfer(
            @RequestParam("fromId") Long fromId,
            @RequestParam("toId") Long toId,
            @RequestParam("amount") BigDecimal amount
    ) {
     */

    @PreAuthorize("hasAnyRole('JyUser')")
    @GetMapping(value = "/globalId/{idstr}")
    public Teacher getGlobalId(@PathVariable final String idstr) {
        Tool.ResolvedGuuid gId =  Tool.fromGluuId(idstr);
        UUID sid = gId.getId();
        String stype = gId.getType();
//版本1 Time-based UUID，版本4 Randomly generated UUID；
//物理数据库推荐上UUID v4版本的； JDK只提供Version 3和Version 4；
//PostgreSQL的UUID也是Version 4的。没法提取时间戳！ 绝对随机的数字，生成的id相似度太低了。
        int uversion=sid.version();
        Teacher teacher=new Teacher(stype, sid.toString(), "版本"+uversion);
        return teacher;
    }
    /**
     * 将type和uuid转换为GraphQL Global ID
     */
    @PostMapping("/uuid2gid")
    public ResponseEntity<GlobalIdResponse> encodeGlobalId(@Valid @RequestBody GlobalIdRequest request) {
        try {
            UUID uuid=UUID.fromString(request.getUuid());
            String globalId = Tool.toGlobalId(request.getType(), uuid);
            GlobalIdResponse response = GlobalIdResponse.builder()
                    .success(true)
                    .globalId(globalId)
                    .type(request.getType())
                    .uuid(request.getUuid())
                    .message("Global ID generated successfully")
                    .build();
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            GlobalIdResponse errorResponse = GlobalIdResponse.builder()
                    .success(false)
                    .message("Failed to generate Global ID: " + e.getMessage())
                    .build();
            return ResponseEntity.badRequest().body(errorResponse);
        }
    }
    /**测试，临时用：
     * */
    @MetricsLogger
    @Transactional(rollbackFor=Exception.class, timeout=600)
    @GetMapping(value = "/removeErrorRecs")
    public Boolean setupFromLegacy_Ls临时Isp消除(String arg) {
        Pageable pageable= PageRequest.of(0, 20);
        QIsp q=QIsp.isp;        //Isp表设置dev_id可实际Eqp不存在的? q.dev.id.isNull()也不行啊:不正常数据，关联无效，逻辑？
        Predicate predicate= q.no.isNull().and(q.bus.isNull()).and(q.report.isNull());      //若是关系.or.导致只能是全表搜索的
        QBeanMy<?> piExp=new QBeanMy<Isp>(Isp.class, q.id );
        piExp.bindLeftJoin(q.dev);      //若q.dev.id.isNull()条件用了？ 默认Cross join; 下面这条执行很慢！ 外键索引还没有建立？
        Slice<IspPi> slice= iSPRepository.findBy(piExp, predicate, (query)-> {
            FluentQuery.FetchableFluentQuery<IspPi> queryUse = query.as(IspPi.class);
            return  queryUse.page(pageable);
        });
        List<IspPi> result=slice.getContent();
        //奇？IDEA的DBconsole工具竟然中间状态查出来，后面被CRDB回滚了。from isp where no is null and bus_id is null and isp.report_id is null
        log.info("准备清理Isp错误 条数{}", result.size());
        List<UUID> ids= result.stream().map(isppi->isppi.getId()).collect(Collectors.toList());
        iSPRepository.deleteAllByIdInBatch(ids);     //自己isp.ID删除也很慢 !!
        return true;
    }
    /**对接JC
     * 单位 /isp/untMge/sync  AmrUntQry.setQueryType(0);
     * */
    @MetricsLogger
    @Transactional(rollbackFor=Exception.class, timeout=600)
    @GetMapping(value = "/unitOf")
    public Boolean do获取单位台账(String arg) {
        final SimplePropertyPreFilter jsonIgnoreFilter = new SimplePropertyPreFilter();
        Map<String, String> busiMap1 = new HashMap<>();
        String   user_name =jcusername;
        String passwd =jcpassword;
        busiMap1.put("user_name", user_name);
        busiMap1.put("passwd", passwd);
        String token = DtHandleUtil.gettoken(busiMap1);
        //op_code ?       busiData.put("ope_cod", "regeqpquery");
        String url="https://220.160.53.129:18093/seds-gateway/api/isp/untMge/sync";
//        String url="http://211.138.144.118:19000/seds-svc/api/isp/untMge/sync";
        //qparams.add(new BasicNameValuePair("token", token));
//        String token="2736457fa5877c4f05968397c417352d";
        Map<String, String> busiMap = new HashMap<>();
        busiMap.put("user_name", user_name);
        busiMap.put("passwd", passwd);

//{"data":[{"token":"61d53caa0028851a8964c172924a67bb"}],"success":"true","message":"获取成功"}
//        Map<String, String> resp= DtHandleUtil.callJcHttpPost(user_name,passwd,url,"",token);
        Map<String, String> busiData = new HashMap<>();
        String returnStr = "RC72995";
        busiData.put("OIDNO", returnStr);
        busiData.put("ope_cod", "regeqpquery");
//        Map msg = getJcDataServiceNew.callHttpService(busiData);
        AmrUntQry amrUntQry=new AmrUntQry();
        amrUntQry.setQueryType(0);
        String reqJsonData= JSON.toJSONString(amrUntQry, jsonIgnoreFilter);          //AmrUntQry qry param

        Map<String, String> resp=DtHandleUtil.callJcHttpPost(user_name,passwd,url,reqJsonData,token);

//            Map msg = DtHandleUtil.callHttpServicenew(busiData, token);
//        Map msg =DtHandleUtil.callHttpService(busiData);
//        String data = resp.get("retData") == null ? "" : resp.get("retData");
//        var any=resp.get("retCod");
        //判断响应参数是否需要进行参数匹配
        String jyFields = "";
        if (true) {
            //响应参数转化
//            Map<String, Object> retMap = dtDataHandleService.dtDataMatchHandle(api, data, "1", jyKeyFieldType, jcKeyFieldType, isStoService);
//            data = (String) retMap.get("dataInfo");
//            jyFields = JSON.toJSONString(retMap.get("fieldInfo"));
        }
        System.out.println((new String()).format("例行Utilities.average运行=%d", "") );
        return true;
    }
    /**对接JC
     * 有注册的设备 /api/isp/eqpmge/sync  AmrUntQry.setQueryType(0);
     * */
    @MetricsLogger
    @Transactional(rollbackFor=Exception.class, timeout=600)
    @GetMapping(value = "/deviceOf")
    public Boolean do获取设备台账(String arg) {
        final SimplePropertyPreFilter jsonIgnoreFilter = new SimplePropertyPreFilter();
        Map<String, String> busiMap1 = new HashMap<>();
        String   user_name =jcusername;
        String passwd =jcpassword;
        busiMap1.put("user_name", user_name);
        busiMap1.put("passwd", passwd);
        String token = DtHandleUtil.gettoken(busiMap1);
        //op_code ?       busiData.put("ope_cod", "regeqpquery");
        String url="https://220.160.53.129:18093/seds-gateway/api/isp/eqpmge/sync";
//        String url="http://211.138.144.118:19000/seds-svc/api/isp/untMge/sync";
        //qparams.add(new BasicNameValuePair("token", token));
//        String token="2736457fa5877c4f05968397c417352d";
        Map<String, String> busiMap = new HashMap<>();
        busiMap.put("user_name", user_name);
        busiMap.put("passwd", passwd);

//{"data":[{"token":"61d53caa0028851a8964c172924a67bb"}],"success":"true","message":"获取成功"}
//        Map<String, String> resp= DtHandleUtil.callJcHttpPost(user_name,passwd,url,"",token);
        Map<String, String> busiData = new HashMap<>();
        String oidcodStr = "RC72995";
        busiData.put("OIDNO", oidcodStr);
        busiData.put("ope_cod", "regeqpquery");
//        Map msg = getJcDataServiceNew.callHttpService(busiData);
        AmrEqpQry amrQry=new AmrEqpQry();
        amrQry.setQueryType(0);
        amrQry.setOidno(oidcodStr);
        String reqJsonData= JSON.toJSONString(amrQry, jsonIgnoreFilter);          //AmrUntQry qry param
        Map<String, String> respMap = new HashMap<>();
//        Map<String, String> resp=DtHandleUtil.callJcHttpPost(user_name,passwd,url,reqJsonData,token);

//            Map msg = DtHandleUtil.callHttpServicenew(busiData, token);
//        Map msg =DtHandleUtil.callHttpService(busiData);
//        String data = resp.get("retData") == null ? "" : resp.get("retData");
//        var any=resp.get("retCod");
        //判断响应参数是否需要进行参数匹配
            //响应参数转化
//            Map<String, Object> retMap = dtDataHandleService.dtDataMatchHandle(api, data, "1", jyKeyFieldType, jcKeyFieldType, isStoService);
//            data = (String) retMap.get("dataInfo");
//            jyFields = JSON.toJSONString(retMap.get("fieldInfo"));

        try {
            respMap = DtHandleUtil.callJcHttpPost(user_name,passwd,url,reqJsonData,token);
        } catch (Exception ex) {
            respMap.put("retCod", "-1");
            respMap.put("msg", "访问监察接口失败:" + ex.getMessage());
            log.error("访问监察接口", ex);
        }
        String data = respMap.get("retData") == null ? "" : respMap.get("retData");
        final boolean succeed = "1".equals(respMap.get("retCod"));    //YesNoEnum.yes(
        //判断响应参数是否需要进行参数匹配
        String jyFields = "";
        JyjcResponse jyjcResponse = new JyjcResponse();
        jyjcResponse.setStatus(respMap.get("retCod"));
        jyjcResponse.setMsg(respMap.get("msg") == null ? "" : respMap.get("msg"));
        jyjcResponse.setData(data);
        jyjcResponse.setFiledInfo(jyFields);
        jyjcResponse.setTotal(respMap.get("TOTAL"));
        JSONArray arrDato=JSON.parseArray(data);    //.toJSONString(data);
// 解析 JSON 字符串为 List<DataItem>
        List<AmrEqpInfo> dataItems = JSON.parseArray(data, AmrEqpInfo.class);
        // 输出解析后的对象（这里只输出第一个对象作为示例）
        if (!dataItems.isEmpty()) {
            AmrEqpInfo dataItem = dataItems.get(0);
            System.out.println("BASE_INFO: " + dataItem.getBaseInfo());
            System.out.println("PARAMS: " + dataItem.getParams().getVesselParam());
        }

        return true;
    }
    /**测试 启动任务
     * */
    @MetricsLogger
    @Transactional(rollbackFor=Exception.class, timeout=600)
    @GetMapping(value = "/quartz")
    public Boolean testQuartz(String arg) throws SchedulerException{
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
        scheduler.start();
//
//        // 动态创建JobDetail
//        JobDetail jobDetail = createJobDetail("dynamicJob", "dynamicGroup", MyQuartzJob.class);
//
//        // 创建Trigger
//        Trigger trigger = TriggerBuilder.newTrigger()
//                .withIdentity("dynamicTrigger", "dynamicGroup")
//                .startNow()
//                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
//                        .withIntervalInSeconds(15)
//                        .repeatForever())
//                .build();
//
//        // 将作业和触发器注册到Scheduler
//        scheduler.scheduleJob(jobDetail, trigger);
        return true;
    }
    /**测试 取消任务
     * */
    @MetricsLogger
    @Transactional(rollbackFor=Exception.class, timeout=600)
    @GetMapping(value = "/quartzPau")
    public Boolean testQuartz3(String arg) throws SchedulerException{
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
        JobKey jobKey = new JobKey("dynamicJob", "dynamicGroup");
        scheduler.pauseJob(jobKey);
        return true;
    }
    /**测试 删掉任务
     * */
    @MetricsLogger
    @Transactional(rollbackFor=Exception.class, timeout=600)
    @GetMapping(value = "/quartzDel")
    public Boolean testQuartz4(String arg) throws SchedulerException{
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
        JobKey jobKey = new JobKey("dynamicJob", "dynamicGroup");
        scheduler.deleteJob(jobKey);
        //scheduler.shutdown();平滑地关闭  //或 scheduler.shutdownNow();
        return true;
    }
}


//Spring Boot 和 Quarkus 的区别  https://blog.csdn.net/allway2/article/details/122777303
